#ifndef __AMS_H__
#define __AMS_H__

#include "lvgl.h"
#include "messager.h"
#include "cmsis_os.h"
#include "cmsis_mem.h"

#define ams_assert      osAssert

#define ams_malloc      osMalloc
#define ams_free        osFree

#define AMS_UNUSE(x)    ((x) = (x))

// ##
#define GET_IMAGE_W(pIMAGE) ((pIMAGE)->header.w)
#define GET_IMAGE_H(pIMAGE) ((pIMAGE)->header.h)

// ##
#define TO_STRING(x) #x

#define ACTIVITY_OPS_IMPLEMENT_DECLARE(id, img, flag)   static void app_prepare(void *event);           \
                                                        static void app_start(void *event);             \
                                                        static void app_stop(void *event);              \
                                                        static void *app_create(void *event);           \
                                                        static void *app_destroy(void *event);          \
                                                        static void app_event_handle(void *event);      \
                                                        static void app_gesture_handle(void *event);    \
                                                        static ams_ops_t ams_ops_##id =                 \
                                                        {                                               \
                                                            .prepare = app_prepare,                     \
                                                            .start = app_start,                         \
                                                            .stop = app_stop,                           \
                                                            .create = app_create,                       \
                                                            .destroy = app_destroy,                     \
                                                            .handler = app_event_handle,                \
                                                            .gesture = app_gesture_handle,              \
                                                        };                                              \
                                                        const ams_activity_t ams_app_##id =             \
                                                        {                                               \
                                                            .icon = img,                                \
                                                            .name = TO_STRING(id),                      \
                                                            .ops = &ams_ops_##id,                       \
                                                            .attr = flag,                               \
                                                        };                                              \

// ##
typedef void (*event_handle_t)(void *event);
typedef void (*gesture_handle_t)(void *event);
typedef void (*app_prepare_t)(void *content);
typedef void (*app_start_t)(void *content);
typedef void (*app_stop_t)(void *content);
typedef void *(*app_create_t)(void *content);
typedef void *(*app_destroy_t)(void *content);

typedef struct __ams_ops_t
{
    app_prepare_t prepare;
    app_start_t start;
    app_stop_t stop;
    app_create_t create;
    app_destroy_t destroy;
    event_handle_t handler;
    gesture_handle_t gesture;
}ams_ops_t;

// ##
typedef struct __ams_profile_t
{
    const lv_img_dsc_t *icon;
    char *name;
}ams_profile_t;

typedef struct __ams_profile_node_t
{
    const lv_img_dsc_t *icon;
    char *name;
    struct __ams_profile_node_t *next;
}ams_profile_node_t;

// ##
typedef struct __ams_item_t
{
    const lv_img_dsc_t *icon;
    char *name;
    void *ui;
    void *custom;
    ams_ops_t *ops;
    uint32_t attr;
}ams_activity_t;

typedef struct __ams_node_t
{
    ams_activity_t *item;
    struct __ams_node_t *next;
}ams_node_t;

typedef struct
{
    uint32_t msg_id;
    void *content;
    uint32_t size;
}ams_event_t;

// ##
#define ACTIVITY_ATTR_FLAG_HOME     ((uint32_t)(1 << 0))
#define ACTIVITY_ATTR_FLAG_LIST     ((uint32_t)(1 << 1))
#define ACTIVITY_ATTR_FLAG_APP      ((uint32_t)(1 << 2))

typedef enum __ams_gesture_t
{
    GESTURE_SLIDE_TO_TOP = 0,
    GESTURE_SLIDE_TO_BOTTOM,
    GESTURE_SLIDE_TO_LEFT,
    GESTURE_SLIDE_TO_RIGHT,
}ams_gesture_t;

typedef enum __ams_dir_t
{
    DIR_SLIDE_TO_NONE = 0,
    DIR_SLIDE_TO_TOP,
    DIR_SLIDE_TO_BOTTOM,
    DIR_SLIDE_TO_LEFT,
    DIR_SLIDE_TO_RIGHT,
    DIR_COVER_TO_TOP,
    DIR_COVER_TO_BOTTOM,
    DIR_COVER_TO_LEFT,
    DIR_COVER_TO_RIGHT,
}ams_dir_t;

// ##
void ams_activity_register(const ams_activity_t *item);

// ##
void ams_list_create(void);

// ##
void ams_event_listener_register(const msg_t msg);

// ##
void ams_event_listener_unregister(const msg_t msg);

// ##
void ams_init(const mMessager_t messager);

// ##
void ams_event_handle(ams_event_t *event);

// ##
ams_activity_t *ams_search_by_name(char *name);

// ##
void ams_switch_by_name(char *name, ams_dir_t dir);

// ##
void ams_switch_to(ams_activity_t *next, ams_dir_t dir);

// ##
void *ams_activity_start(ams_activity_t *activity, ams_dir_t dir);

/**
 * @description:
 * @param {ams_profile_node_t} *
 * @return {*}
 */
void ams_activity_get_list(ams_profile_node_t **list);

#endif

